#include "KeyboardState.h"
#include <iostream>

KeyboardState::KeyboardState()
{
    this->vector_onestep = vector<Key*>();

    //
    //
    //
    K_Return.state = KeyReleased;
    //
    K_Escape.state = KeyReleased;
    K_Space.state = KeyReleased;
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    K_0.state = KeyReleased;
    K_1.state = KeyReleased;
    K_2.state = KeyReleased;
    K_3.state = KeyReleased;
    K_4.state = KeyReleased;
    K_5.state = KeyReleased;
    K_6.state = KeyReleased;
    K_7.state = KeyReleased;
    K_8.state = KeyReleased;
    K_9.state = KeyReleased;
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    K_A.state = KeyReleased;
    K_B.state = KeyReleased;
    K_C.state = KeyReleased;
    K_D.state = KeyReleased;
    K_E.state = KeyReleased;
    K_F.state = KeyReleased;
    K_G.state = KeyReleased;
    K_H.state = KeyReleased;
    K_I.state = KeyReleased;
    K_J.state = KeyReleased;
    K_K.state = KeyReleased;
    K_L.state = KeyReleased;
    K_M.state = KeyReleased;
    K_N.state = KeyReleased;
    K_O.state = KeyReleased;
    K_P.state = KeyReleased;
    K_Q.state = KeyReleased;
    K_R.state = KeyReleased;
    K_S.state = KeyReleased;
    K_T.state = KeyReleased;
    K_U.state = KeyReleased;
    K_V.state = KeyReleased;
    K_W.state = KeyReleased;
    K_X.state = KeyReleased;
    K_Y.state = KeyReleased;
    K_Z.state = KeyReleased;
    //
    K_KP0.state = KeyReleased;
    K_KP1.state = KeyReleased;
    K_KP2.state = KeyReleased;
    K_KP3.state = KeyReleased;
    K_KP4.state = KeyReleased;
    K_KP5.state = KeyReleased;
    K_KP6.state = KeyReleased;
    K_KP7.state = KeyReleased;
    K_KP8.state = KeyReleased;
    K_KP9.state = KeyReleased;
    //
    //
    //
    //
    //
    K_KPEnter.state = KeyReleased;
    //
    K_Left.state = KeyReleased;
    K_Right.state = KeyReleased;
    K_Up.state = KeyReleased;
    K_Down.state = KeyReleased;
    //
    //
    //
    //
    K_F1.state = KeyReleased;
    K_F2.state = KeyReleased;
    K_F3.state = KeyReleased;
    K_F4.state = KeyReleased;
    K_F5.state = KeyReleased;
    K_F6.state = KeyReleased;
    K_F7.state = KeyReleased;
    K_F8.state = KeyReleased;
    K_F9.state = KeyReleased;
    K_F10.state = KeyReleased;
    K_F11.state = KeyReleased;
    K_F12.state = KeyReleased;
    //
    //
    //
    K_RightShift.state = KeyReleased;
    K_LeftShift.state = KeyReleased;
    K_RightControl.state = KeyReleased;
    K_LeftControl.state = KeyReleased;
    K_RightAlt.state = KeyReleased;
    K_LeftAlt.state = KeyReleased;
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    K_Return.prevState = KeyReleased;
    //
    K_Escape.prevState = KeyReleased;
    K_Space.prevState = KeyReleased;
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    K_0.prevState = KeyReleased;
    K_1.prevState = KeyReleased;
    K_2.prevState = KeyReleased;
    K_3.prevState = KeyReleased;
    K_4.prevState = KeyReleased;
    K_5.prevState = KeyReleased;
    K_6.prevState = KeyReleased;
    K_7.prevState = KeyReleased;
    K_8.prevState = KeyReleased;
    K_9.prevState = KeyReleased;
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    K_A.prevState = KeyReleased;
    K_B.prevState = KeyReleased;
    K_C.prevState = KeyReleased;
    K_D.prevState = KeyReleased;
    K_E.prevState = KeyReleased;
    K_F.prevState = KeyReleased;
    K_G.prevState = KeyReleased;
    K_H.prevState = KeyReleased;
    K_I.prevState = KeyReleased;
    K_J.prevState = KeyReleased;
    K_K.prevState = KeyReleased;
    K_L.prevState = KeyReleased;
    K_M.prevState = KeyReleased;
    K_N.prevState = KeyReleased;
    K_O.prevState = KeyReleased;
    K_P.prevState = KeyReleased;
    K_Q.prevState = KeyReleased;
    K_R.prevState = KeyReleased;
    K_S.prevState = KeyReleased;
    K_T.prevState = KeyReleased;
    K_U.prevState = KeyReleased;
    K_V.prevState = KeyReleased;
    K_W.prevState = KeyReleased;
    K_X.prevState = KeyReleased;
    K_Y.prevState = KeyReleased;
    K_Z.prevState = KeyReleased;
    //
    K_KP0.prevState = KeyReleased;
    K_KP1.prevState = KeyReleased;
    K_KP2.prevState = KeyReleased;
    K_KP3.prevState = KeyReleased;
    K_KP4.prevState = KeyReleased;
    K_KP5.prevState = KeyReleased;
    K_KP6.prevState = KeyReleased;
    K_KP7.prevState = KeyReleased;
    K_KP8.prevState = KeyReleased;
    K_KP9.prevState = KeyReleased;
    //
    //
    //
    //
    //
    K_KPEnter.prevState = KeyReleased;
    //
    K_Left.prevState = KeyReleased;
    K_Right.prevState = KeyReleased;
    K_Up.prevState = KeyReleased;
    K_Down.prevState = KeyReleased;
    //
    //
    //
    //
    K_F1.prevState = KeyReleased;
    K_F2.prevState = KeyReleased;
    K_F3.prevState = KeyReleased;
    K_F4.prevState = KeyReleased;
    K_F5.prevState = KeyReleased;
    K_F6.prevState = KeyReleased;
    K_F7.prevState = KeyReleased;
    K_F8.prevState = KeyReleased;
    K_F9.prevState = KeyReleased;
    K_F10.prevState = KeyReleased;
    K_F11.prevState = KeyReleased;
    K_F12.prevState = KeyReleased;
    //
    //
    //
    K_RightShift.prevState = KeyReleased;
    K_LeftShift.prevState = KeyReleased;
    K_RightControl.prevState = KeyReleased;
    K_LeftControl.prevState = KeyReleased;
    K_RightAlt.prevState = KeyReleased;
    K_LeftAlt.prevState = KeyReleased;
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
}
KeyboardState::~KeyboardState()
{
    
}


void KeyboardState::setState(Key* key, bool keydown)
{
    switch (key->state)
    {
        case KeyPressed: 
            if (!keydown)
            {
                //cout << "enter case KeyPressed" << endl;
                vector_onestep.push_back(key);
                key->prevState = KeyPressed;
                key->state = KeyReleased;
            } break;
        case KeyReleased:
            if (keydown)
            {
                //cout << "enter case KeyReleased" << endl;
                vector_onestep.push_back(key);
                key->prevState = KeyReleased;
                key->state = KeyPressed;
            } break;
    }
}
void KeyboardState::preUpdate()
{
    vector<Key*>::iterator it = vector_onestep.begin();
    while (it < vector_onestep.end())
    {
        (*it)->prevState = (*it)->state;
        ++it;
    }
    vector_onestep.clear();
}
void KeyboardState::update(SDL_Event events, bool keydown)
{
    switch (events.key.keysym.sym)
    {
        //case SDLK_BACKSPACE
        //case SDLK_TAB
        //case SDLK_CLEAR
        case SDLK_RETURN: setState(&K_Return, keydown); break;
        //case SDLK_PAUSE
        case SDLK_ESCAPE: setState(&K_Escape, keydown); break;
        case SDLK_SPACE: setState(&K_Space, keydown); break;
        //case SDLK_EXCLAIM
        //case SDLK_QUOTEDBL
        //case SDLK_HASH
        //case SDLK_DOLLAR
        //case SDLK_AMPERSAND
        //case SDLK_QUOTE
        //case SDLK_LEFTPAREN
        //case SDLK_RIGHTPAREN
        //case SDLK_ASTERISK
        //case SDLK_PLUS
        //case SDLK_COMMA
        //case SDLK_MINUS
        //case SDLK_PERIOD
        //case SDLK_SLASH
        case SDLK_0: setState(&K_0, keydown); break;
        case SDLK_1: setState(&K_1, keydown); break;
        case SDLK_2: setState(&K_2, keydown); break;
        case SDLK_3: setState(&K_3, keydown); break;
        case SDLK_4: setState(&K_4, keydown); break;
        case SDLK_5: setState(&K_5, keydown); break;
        case SDLK_6: setState(&K_6, keydown); break;
        case SDLK_7: setState(&K_7, keydown); break;
        case SDLK_8: setState(&K_8, keydown); break;
        case SDLK_9: setState(&K_9, keydown); break;
        //case SDLK_COLON
        //case SDLK_SEMICOLON
        //case SDLK_LESS
        //case SDLK_EQUALS
        //case SDLK_GREATER
        //case SDLK_QUESTION
        //case SDLK_AT
        //case SDLK_LEFTBRACKET
        //case SDLK_BACKSLASH
        //case SDLK_RIGHTBRACKET
        //case SDLK_CARET
        //case SDLK_UNDERSCORE
        //case SDLK_BACKQUOTE
        case SDLK_a: setState(&K_A, keydown); break;
        case SDLK_b: setState(&K_B, keydown); break;
        case SDLK_c: setState(&K_C, keydown); break;
        case SDLK_d: setState(&K_D, keydown); break;
        case SDLK_e: setState(&K_E, keydown); break;
        case SDLK_f: setState(&K_F, keydown); break;
        case SDLK_g: setState(&K_G, keydown); break;
        case SDLK_h: setState(&K_H, keydown); break;
        case SDLK_i: setState(&K_I, keydown); break;
        case SDLK_j: setState(&K_J, keydown); break;
        case SDLK_k: setState(&K_K, keydown); break;
        case SDLK_l: setState(&K_L, keydown); break;
        case SDLK_m: setState(&K_M, keydown); break;
        case SDLK_n: setState(&K_N, keydown); break;
        case SDLK_o: setState(&K_O, keydown); break;
        case SDLK_p: setState(&K_P, keydown); break;
        case SDLK_q: setState(&K_Q, keydown); break;
        case SDLK_r: setState(&K_R, keydown); break;
        case SDLK_s: setState(&K_S, keydown); break;
        case SDLK_t: setState(&K_T, keydown); break;
        case SDLK_u: setState(&K_U, keydown); break;
        case SDLK_v: setState(&K_V, keydown); break;
        case SDLK_w: setState(&K_W, keydown); break;
        case SDLK_x: setState(&K_X, keydown); break;
        case SDLK_y: setState(&K_Y, keydown); break;
        case SDLK_z: setState(&K_Z, keydown); break;
        //case SDLK_DELETE
        case SDLK_KP0: setState(&K_KP0, keydown); break;
        case SDLK_KP1: setState(&K_KP1, keydown); break;
        case SDLK_KP2: setState(&K_KP2, keydown); break;
        case SDLK_KP3: setState(&K_KP3, keydown); break;
        case SDLK_KP4: setState(&K_KP4, keydown); break;
        case SDLK_KP5: setState(&K_KP5, keydown); break;
        case SDLK_KP6: setState(&K_KP6, keydown); break;
        case SDLK_KP7: setState(&K_KP7, keydown); break;
        case SDLK_KP8: setState(&K_KP8, keydown); break;
        case SDLK_KP9: setState(&K_KP9, keydown); break;
        //case SDLK_KP_PERIOD
        //case SDLK_KP_DIVIDE
        //case SDLK_KP_MULTIPLY
        //case SDLK_KP_MINUS
        //case SDLK_KP_PLUS
        case SDLK_KP_ENTER: setState(&K_KPEnter, keydown); break;
        //case SDLK_KP_EQUALS
        case SDLK_UP: setState(&K_Up, keydown); break;
        case SDLK_DOWN: setState(&K_Down, keydown); break;
        case SDLK_RIGHT: setState(&K_Right, keydown); break;
        case SDLK_LEFT: setState(&K_Left, keydown); break;
        //case SDLK_INSERT
        //case SDLK_HOME
        //case SDLK_END
        //case SDLK_PAGEUP
        //case SDLK_PAGEDOWN
        case SDLK_F1: setState(&K_F1, keydown); break;
        case SDLK_F2: setState(&K_F2, keydown); break;
        case SDLK_F3: setState(&K_F3, keydown); break;
        case SDLK_F4: setState(&K_F4, keydown); break;
        case SDLK_F5: setState(&K_F5, keydown); break;
        case SDLK_F6: setState(&K_F6, keydown); break;
        case SDLK_F7: setState(&K_F7, keydown); break;
        case SDLK_F8: setState(&K_F8, keydown); break;
        case SDLK_F9: setState(&K_F9, keydown); break;
        case SDLK_F10: setState(&K_F10, keydown); break;
        case SDLK_F11: setState(&K_F11, keydown); break;
        case SDLK_F12: setState(&K_F12, keydown); break;
        //case SDLK_NUMLOCK
        //case SDLK_CAPSLOCK
        //case SDLK_SCROLLOCK
        case SDLK_RSHIFT: setState(&K_RightShift, keydown); break;
        case SDLK_LSHIFT: setState(&K_LeftShift, keydown); break;
        case SDLK_RCTRL: setState(&K_RightControl, keydown); break;
        case SDLK_LCTRL: setState(&K_LeftControl, keydown); break;
        case SDLK_RALT: setState(&K_RightAlt, keydown); break;
        case SDLK_LALT: setState(&K_LeftAlt, keydown); break;
        //case SDLK_RMETA
        //case SDLK_LMETA
        //case SDLK_LSUPER
        //case SDLK_RSUPER
        //case SDLK_MODE
        //case SDLK_HELP
        //case SDLK_PRINT
        //case SDLK_SYSREQ
        //case SDLK_BREAK
        //case SDLK_MENU
        //case SDLK_POWER
        //case SDLK_EURO
    }
}
